home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-13 | 17.4 KB | 654 lines | [TEXT/KAHL] |
- ///--------------------------------------------------------------------------------------
- // ShipSprite.c
- //
- // Created: 6/18/92 at 2:29:31 PM
- // By: Tony Myles
- //
- // Copyright: © 1992-93 Tony Myles, All rights reserved worldwide.
- ///--------------------------------------------------------------------------------------
-
-
- #ifndef _H_math
- #include <math.h>
- #endif
-
- #ifndef __FIXMATH__
- #include <FixMath.h>
- #endif
-
- #ifndef __SPRITEWORLD__
- #include <SpriteWorld.h>
- #endif
-
- #ifndef __SPRITELAYER__
- #include <SpriteLayer.h>
- #endif
-
- #ifndef __BLITPIXIE__
- #include <BlitPixie.h>
- #endif
-
- #ifndef __GAMEUTILS__
- #include <GameUtils.h>
- #endif
-
- #ifndef __SOUNDUTILS__
- #include <SoundUtils.h>
- #endif
-
- #ifndef __DEBUGUTILS__
- #include <DebugUtils.h>
- #endif
-
- #ifndef __SHIPSPRITE__
- #include "ShipSprite.h"
- #endif
-
-
- Boolean gShipSoundDone;
- RgnHandle gWorkRgn;
-
-
- ///--------------------------------------------------------------------------------------
- // CreateShipSprite
- ///--------------------------------------------------------------------------------------
-
- OSErr CreateShipSprite(
- ShipSpritePtr* shipSpriteP)
- {
- OSErr err;
- ShipSpritePtr tempShipSpriteP;
-
- *shipSpriteP = NULL;
-
- tempShipSpriteP = (ShipSpritePtr)NewPtr(sizeof(ShipSpriteRec));
-
- if (tempShipSpriteP != NULL)
- {
- // create the ship sprite
- err = SWCreateSpriteFromCIconResource((SpritePtr*)shipSpriteP, tempShipSpriteP,
- kShipFrameResID, kNumberOfShipFrames, kFatMask);
- }
- else
- {
- err = MemError();
- }
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // DisposeShipSprite
- ///--------------------------------------------------------------------------------------
-
- void DisposeShipSprite(
- ShipSpritePtr shipSpriteP)
- {
- if (shipSpriteP != NULL)
- {
- DisposeShipSounds(shipSpriteP);
-
- SWDisposeSprite((SpritePtr)shipSpriteP, true);
- }
-
- DisposeRgn(gWorkRgn);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // InitShipSprite
- ///--------------------------------------------------------------------------------------
-
- void InitShipSprite(
- ShipSpritePtr shipSpriteP,
- SpriteWorldPtr shipSpriteWorldP,
- SpriteLayerPtr shipSpriteLayerP,
- SpriteLayerPtr shotSpriteLayerP)
- {
- gWorkRgn = NewRgn();
- gShipSoundDone = true;
-
- // initialize some stuff
- shipSpriteP->shipSndChannelP = NULL;
- shipSpriteP->shipSpriteWorldP = shipSpriteWorldP;
- shipSpriteP->shipSpriteLayerP = shipSpriteLayerP;
- shipSpriteP->shotSpriteLayerP = shotSpriteLayerP;
- shipSpriteP->shipWrapRect = shipSpriteWorldP->backFrameP->frameRect;
-
- shipSpriteP->shotCounter = 0;
- shipSpriteP->shotTickDelay = 0;
-
- shipSpriteP->shipVelocity.h = 0;
- shipSpriteP->shipVelocity.v = 0;
- shipSpriteP->shipHorizLoc = 0;
- shipSpriteP->shipVertLoc = 0;
-
- shipSpriteP->isAlive = false;
-
- // initialize the velocity table
- CreateVelocityTable(shipSpriteP->angularVelocityTable, kNumberOfShipFrames, .751215935);
- CreateVelocityTable(shipSpriteP->shotVelocityTable, kNumberOfShipFrames, 10.0);
-
- // add the ship to the layer
- SWAddSprite(shipSpriteP->shipSpriteLayerP, (SpritePtr)shipSpriteP);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateShipSounds
- ///--------------------------------------------------------------------------------------
-
- OSErr CreateShipSounds(
- ShipSpritePtr shipSpriteP)
- {
- OSErr err;
-
- // initialize ship sound stuff
- shipSpriteP->shipSndChannelP = NULL;
- shipSpriteP->explosionSndH = NULL;
- shipSpriteP->thrustSndH = NULL;
- shipSpriteP->shotSndH = NULL;
-
- // create a new sound channel
- err = SndNewChannel(&shipSpriteP->shipSndChannelP, sampledSynth,
- initMono, (SndCallBackProcPtr)ShipSoundCallBack);
-
- if (err == noErr)
- {
- shipSpriteP->shipSndChannelP->userInfo = 0;
- shipSpriteP->shipSndCmd.cmd = callBackCmd;
- shipSpriteP->shipSndCmd.param2 = (long)&gShipSoundDone;
-
- // load the explosion sound
- shipSpriteP->explosionSndH = GetSoundResource(kExplosionSoundResID, &err);
- }
-
- if (err == noErr)
- {
- // load the thrust sound
- shipSpriteP->thrustSndH = GetSoundResource(kThrustSoundResID, &err);
- }
-
- if (err == noErr)
- {
- // load the shot sound
- shipSpriteP->shotSndH = GetSoundResource(kShotSoundResID, &err);
- }
-
- if (err != noErr)
- {
- DisposeShipSounds(shipSpriteP);
- }
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // DisposeShipSounds
- ///--------------------------------------------------------------------------------------
-
- void DisposeShipSounds(
- ShipSpritePtr shipSpriteP)
- {
- if (shipSpriteP->shipSndChannelP != NULL)
- {
- (void)SndDisposeChannel(shipSpriteP->shipSndChannelP, true);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SetupShipSprite
- ///--------------------------------------------------------------------------------------
-
- void SetupShipSprite(
- ShipSpritePtr shipSpriteP)
- {
- short shotSpriteNum;
-
- SWLockSprite((SpritePtr)shipSpriteP);
-
- SWSetSpriteMoveProc((SpritePtr)shipSpriteP, (MoveProcPtr)ShipMoveProc);
- SWSetSpriteFrameProc((SpritePtr)shipSpriteP, (FrameProcPtr)ShipFrameProc);
- SWSetSpriteCollideProc((SpritePtr)shipSpriteP, (CollideProcPtr)ShipCollideProc);
- SWSetSpriteDrawProc((SpritePtr)shipSpriteP, BlitPixieMaskDrawProc);
-
- SWSetSpriteMoveTime((SpritePtr)shipSpriteP, -1);
- SWSetSpriteMoveBounds((SpritePtr)shipSpriteP, &shipSpriteP->shipWrapRect);
- SWSetSpriteFrameTime((SpritePtr)shipSpriteP, kShipFrameTime);
- SWSetSpriteFrameAdvance((SpritePtr)shipSpriteP, 0);
- SWSetSpriteLocation((SpritePtr)shipSpriteP,
- shipSpriteP->shipWrapRect.right / 2,
- shipSpriteP->shipWrapRect.bottom / 2);
- SWSetSpriteVisible((SpritePtr)shipSpriteP, false);
-
- shipSpriteP->shipHorizLoc = ff(shipSpriteP->shipWrapRect.right / 2);
- shipSpriteP->shipVertLoc = ff(shipSpriteP->shipWrapRect.bottom / 2);
-
- for (shotSpriteNum = 0; shotSpriteNum < kNumberOfShotSprites; shotSpriteNum++)
- {
- SWLockSprite((SpritePtr)shipSpriteP->shotSpriteArray[shotSpriteNum]);
- SWSetSpriteDrawProc((SpritePtr)shipSpriteP->shotSpriteArray[shotSpriteNum], BlitPixieEraseProc);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateShotSpriteArray
- ///--------------------------------------------------------------------------------------
-
- OSErr CreateShotSpriteArray(
- ShipSpritePtr shipSpriteP)
- {
- OSErr err;
- short shotSpriteNum = 0, numberOfShotSprites;
- ShotSpritePtr* shotSpriteArray = shipSpriteP->shotSpriteArray;
- ShotSpritePtr shotSpriteP, newShotSpriteP;
-
- err = SWCreateSpriteFromPictResource((SpritePtr*)&shotSpriteP,
- shipSpriteP->shotSpriteStorage,
- kShotFrameResID, 0, 1, kNoMask);
-
- if (err == noErr)
- {
- InitShotSprite(shipSpriteP, shotSpriteP);
- shotSpriteArray[0] = shotSpriteP;
-
- for (shotSpriteNum = 1; shotSpriteNum < kNumberOfShotSprites; shotSpriteNum++)
- {
- err = SWCloneSprite((SpritePtr)shotSpriteP, (SpritePtr*)&newShotSpriteP,
- shipSpriteP->shotSpriteStorage + shotSpriteNum);
-
- if (err == noErr)
- {
- InitShotSprite(shipSpriteP, newShotSpriteP);
- shotSpriteArray[shotSpriteNum] = newShotSpriteP;
- }
- else
- {
- break;
- }
- }
- }
-
- if (err != noErr)
- {
- // dispose of any sprites that we managed to create
- numberOfShotSprites = shotSpriteNum;
-
- for (shotSpriteNum = 0; shotSpriteNum < numberOfShotSprites; shotSpriteNum++)
- {
- SWDisposeSprite((SpritePtr)shotSpriteArray[shotSpriteNum], shotSpriteNum == 0);
- }
- }
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // InitShotSprite
- ///--------------------------------------------------------------------------------------
-
- void InitShotSprite(
- ShipSpritePtr shipSpriteP,
- ShotSpritePtr shotSpriteP)
- {
- SWSetSpriteMoveProc((SpritePtr)shotSpriteP, (MoveProcPtr)ShotMoveProc);
- SWSetSpriteMoveTime((SpritePtr)shotSpriteP, kShotMoveTime);
- SWSetSpriteMoveBounds((SpritePtr)shotSpriteP, &shipSpriteP->shipWrapRect);
-
- shotSpriteP->shotVelocity.h = 0L;
- shotSpriteP->shotVelocity.v = 0L;
- shotSpriteP->shotHorizLoc = 0L;
- shotSpriteP->shotVertLoc = 0L;
-
- shotSpriteP->shipSpriteP = shipSpriteP;
- shotSpriteP->shotLife = 0L;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // DisposeShotSprite
- ///--------------------------------------------------------------------------------------
-
- void DisposeShotSprite(
- ShipSpritePtr shipSpriteP)
- {
- ShotSpritePtr shotSpriteP;
- short shotSpriteNum;
-
- ReleaseResource(shipSpriteP->shotSndH);
-
- for (shotSpriteNum = 0; shotSpriteNum < kNumberOfShotSprites; shotSpriteNum++)
- {
- // since we allocated storage for the shot sprites ourself
- // we must dispose of the sprites using this call
- SWCloseSprite((SpritePtr)shipSpriteP->shotSpriteArray[shotSpriteNum], shotSpriteNum == 0);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CreateVelocityTable
- ///--------------------------------------------------------------------------------------
-
- void CreateVelocityTable(
- Velocity* velocityTable,
- short numAngles,
- double radius)
- {
- short i;
- Fixed angle = 0;
- Fixed angleIncrement = DblToFix((double)(kRadiansInCircle / numAngles));
- Fixed fixedRadius = DblToFix(radius);
-
- for (i = 0; i < numAngles; i++)
- {
- velocityTable[i].h = FracMul(FracSin(angle), fixedRadius);
- velocityTable[i].v = -FracMul(FracCos(angle), fixedRadius);
-
- angle += angleIncrement;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ShipMoveProc
- ///--------------------------------------------------------------------------------------
-
- void ShipMoveProc(
- ShipSpritePtr shipSpriteP,
- Point *spriteLoc)
- {
- Point oldSpritePoint = *spriteLoc;
-
- SWWrapSpriteMoveProc((SpritePtr)shipSpriteP, spriteLoc);
-
- if (oldSpritePoint.h != spriteLoc->h || oldSpritePoint.v != spriteLoc->v)
- {
- shipSpriteP->shipHorizLoc = ff(spriteLoc->h);
- shipSpriteP->shipVertLoc = ff(spriteLoc->v);
- }
-
- if (KeyIsDown(kEscapeKey)) // hyperspace
- {
- // set position of ship
- spriteLoc->h = GetRandom(shipSpriteP->shipSprite.moveBoundsRect.left + 10,
- shipSpriteP->shipSprite.moveBoundsRect.right - 10);
- spriteLoc->v = GetRandom(shipSpriteP->shipSprite.moveBoundsRect.top + 10,
- shipSpriteP->shipSprite.moveBoundsRect.bottom - 10);
-
- shipSpriteP->shipHorizLoc = ff(spriteLoc->h);
- shipSpriteP->shipVertLoc = ff(spriteLoc->v);
-
- shipSpriteP->shipVelocity.h = 0L;
- shipSpriteP->shipVelocity.v = 0L;
-
- return;
- }
-
- // check for thrust
- if (KeyIsDown(kShiftKey))
- {
- shipSpriteP->shipVelocity.h += shipSpriteP->angularVelocityTable[shipSpriteP->shipSprite.curFrameIndex].h;
- shipSpriteP->shipVelocity.v += shipSpriteP->angularVelocityTable[shipSpriteP->shipSprite.curFrameIndex].v;
-
- // enforce horizontal speed limit
- if (shipSpriteP->shipVelocity.h > ff(kMaxShipVelocity))
- {
- shipSpriteP->shipVelocity.h = ff(kMaxShipVelocity);
- }
- else if (shipSpriteP->shipVelocity.h < ff(-kMaxShipVelocity))
- {
- shipSpriteP->shipVelocity.h = ff(-kMaxShipVelocity);
- }
-
- // enforce vertical speed limit
- if (shipSpriteP->shipVelocity.v > ff(kMaxShipVelocity))
- {
- shipSpriteP->shipVelocity.v = ff(kMaxShipVelocity);
- }
- else if (shipSpriteP->shipVelocity.v < ff(-kMaxShipVelocity))
- {
- shipSpriteP->shipVelocity.v = ff(-kMaxShipVelocity);
- }
- /*
- // is sound not already playing?
- if (gShipSoundDone)
- {
- // play thrust sound
- if (SndPlay(shipSpriteP->shipSndChannelP, shipSpriteP->thrustSndH, true) == noErr)
- {
- gShipSoundDone = false;
-
- (void)SndDoCommand(shipSpriteP->shipSndChannelP, &shipSpriteP->shipSndCmd, true);
- }
- }
- */
- }
-
- // apply velocity to current position
- shipSpriteP->shipHorizLoc += shipSpriteP->shipVelocity.h;
- shipSpriteP->shipVertLoc += shipSpriteP->shipVelocity.v;
-
- // set position of ship
- spriteLoc->h = FixToShort(shipSpriteP->shipHorizLoc);
- spriteLoc->v = FixToShort(shipSpriteP->shipVertLoc);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // FireAShot
- ///--------------------------------------------------------------------------------------
-
- void FireAShot(
- ShipSpritePtr shipSpriteP)
- {
- register ShotSpritePtr shotSpriteP;
-
- shotSpriteP = shipSpriteP->shotSpriteArray[shipSpriteP->shotCounter];
-
- SWAddSprite(shipSpriteP->shotSpriteLayerP, (SpritePtr)shotSpriteP);
- SWSetSpriteLocation((SpritePtr)shotSpriteP,
- shipSpriteP->shipSprite.destFrameRect.left + kShotPosOffset,
- shipSpriteP->shipSprite.destFrameRect.top + kShotPosOffset);
-
- shotSpriteP->shotLife = 0;
- shotSpriteP->shotHorizLoc = shipSpriteP->shipHorizLoc + ff(kShotPosOffset);
- shotSpriteP->shotVertLoc = shipSpriteP->shipVertLoc + ff(kShotPosOffset);
- shotSpriteP->shotVelocity = shipSpriteP->shotVelocityTable[((SpritePtr)shipSpriteP)->curFrameIndex];
-
- shipSpriteP->shotCounter++;
-
- if (shipSpriteP->shotCounter == kNumberOfShotSprites)
- {
- shipSpriteP->shotCounter = 0;
- }
-
- // play shot sound
- //(void)SndPlay(shipSpriteP->shipSndChannelP, shipSpriteP->shotSndH, true);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ShipFrameProc
- ///--------------------------------------------------------------------------------------
-
- void ShipFrameProc(
- ShipSpritePtr shipSpriteP,
- FramePtr curFrameP,
- long* curFrameIndex)
- {
- /*
- // is the ship exploding?
- if (srcSpriteP->curFrameIndex >= kFirstExplosionFrame)
- {
- // is the ship done exploding
- if (srcSpriteP->curFrameIndex == kLastExplosionFrame)
- {
- *curFrameIndex = kFirstShipFrame;
-
- // set position of ship
- shipSpriteP->isAlive = false;
- }
- else
- {
- (*curFrameIndex)++;
- }
-
- return;
- }
- */
-
- if (KeyIsDown(kLeftArrowKey)) // turn left
- {
- // rotate left
- if (*curFrameIndex == kFirstShipFrame)
- {
- *curFrameIndex = kLastShipFrame;
- }
- else
- {
- (*curFrameIndex)--;
- }
- }
- else if (KeyIsDown(kRightArrowKey)) // turn right
- {
- // rotate right
- if (*curFrameIndex == kLastShipFrame)
- {
- *curFrameIndex = kFirstShipFrame;
- }
- else
- {
- (*curFrameIndex)++;
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ShipCollideProc
- ///--------------------------------------------------------------------------------------
-
- void ShipCollideProc(
- ShipSpritePtr shipSpriteP,
- SpritePtr rockSpriteP,
- Rect* sectRect)
- {
- short newHorizLoc, newVertLoc;
- Rect rgnRect = (**rockSpriteP->curFrameP->maskRgn).rgnBBox;
-
- // move the mask region to the new sprite location
- OffsetRgn(rockSpriteP->curFrameP->maskRgn,
- (rockSpriteP->destFrameRect.left - rgnRect.left) +
- rockSpriteP->curFrameP->offsetPoint.h,
- (rockSpriteP->destFrameRect.top - rgnRect.top) +
- rockSpriteP->curFrameP->offsetPoint.v);
-
- rgnRect = (**shipSpriteP->shipSprite.curFrameP->maskRgn).rgnBBox;
-
- // move the mask region to the new sprite location
- OffsetRgn(shipSpriteP->shipSprite.curFrameP->maskRgn,
- (shipSpriteP->shipSprite.destFrameRect.left - rgnRect.left) +
- shipSpriteP->shipSprite.curFrameP->offsetPoint.h,
- (shipSpriteP->shipSprite.destFrameRect.top - rgnRect.top) +
- shipSpriteP->shipSprite.curFrameP->offsetPoint.v);
-
- SectRgn(rockSpriteP->curFrameP->maskRgn, shipSpriteP->shipSprite.curFrameP->maskRgn, gWorkRgn);
-
- if (!EmptyRgn(gWorkRgn))
- {
- /*
- if (SndPlay(shipSpriteP->shipSndChannelP, shipSpriteP->explosionSndH, true) == noErr)
- {
- gShipSoundDone = false;
-
- (void)SndDoCommand(shipSpriteP->shipSndChannelP, &shipSpriteP->shipSndCmd, true);
- }
- */
- //SWSetSpriteFrame((SpritePtr)shipSpriteP, kFirstExplosionFrame);
- //SWSetSpriteMoveDelta(shipSpriteP, 0, 0);
-
- newHorizLoc = shipSpriteP->shipSprite.moveBoundsRect.right / 2;
- newVertLoc = shipSpriteP->shipSprite.moveBoundsRect.bottom / 2;
-
- shipSpriteP->shipHorizLoc = ff(newHorizLoc);
- shipSpriteP->shipVertLoc = ff(newVertLoc);
-
- shipSpriteP->shipVelocity.h = 0L;
- shipSpriteP->shipVelocity.v = 0L;
-
- SWMoveSprite((SpritePtr)shipSpriteP, newHorizLoc, newVertLoc);
- SWSetSpriteVisible((SpritePtr)shipSpriteP, false);
- SWSetSpriteMoveTime((SpritePtr)shipSpriteP, -1);
-
- shipSpriteP->isAlive = false;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ShotMoveProc
- ///--------------------------------------------------------------------------------------
-
- void ShotMoveProc(
- ShotSpritePtr shotSpriteP,
- Point *spriteLoc)
- {
- if (!shotSpriteP->shotSprite.isVisible)
- {
- SWRemoveSprite(shotSpriteP->shipSpriteP->shotSpriteLayerP, (SpritePtr)shotSpriteP);
- SWSetSpriteVisible((SpritePtr)shotSpriteP, true);
- }
- else
- {
- Point oldSpriteLoc = *spriteLoc;
-
- SWWrapSpriteMoveProc((SpritePtr)shotSpriteP, spriteLoc);
-
- if (spriteLoc->h != oldSpriteLoc.h || spriteLoc->v != oldSpriteLoc.v)
- {
- shotSpriteP->shotHorizLoc = ff(spriteLoc->h);
- shotSpriteP->shotVertLoc = ff(spriteLoc->v);
- }
-
- if (shotSpriteP->shotLife == kShotLifeExpectancy)
- {
- shotSpriteP->shotLife = 0L;
-
- SWSetSpriteVisible((SpritePtr)shotSpriteP, false);
- }
- else
- {
- shotSpriteP->shotLife++;
-
- // apply velocity to current position
- shotSpriteP->shotHorizLoc += shotSpriteP->shotVelocity.h;
- shotSpriteP->shotVertLoc += shotSpriteP->shotVelocity.v;
-
- // set position of shot
- spriteLoc->h = FixToShort(shotSpriteP->shotHorizLoc);
- spriteLoc->v = FixToShort(shotSpriteP->shotVertLoc);
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ShipSoundCallBack
- ///--------------------------------------------------------------------------------------
-
- pascal void ShipSoundCallBack(
- SndChannelPtr sndChannelP,
- SndCommand *sndCmdP)
- {
- // a pointer to gSoundDone is in param2
- *(Boolean*)sndCmdP->param2 = true;
- }
-
-
-